package org.luxor.common.netty.config.properties;

import org.luxor.common.netty.config.option.GrantOption;
import org.luxor.common.netty.config.option.ServerNameOption;
import org.luxor.common.netty.config.option.SslOption;
import org.luxor.commons.core.utils.UuidUtils;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;

import java.util.Collections;
import java.util.Set;

/**
 * 服务端配置
 *
 * @author Mr.yan @date 2023/8/22
 */
@ConfigurationProperties(prefix = NettyServerProperties.PREFIX)
public class NettyServerProperties {
    public static final String PREFIX = "spring.netty.server";

    private static final Boolean DEFAULT_ENABLED = Boolean.FALSE;
    private static final ServerNameOption DEF_SERVER_NAME = ServerNameOption.NONE;
    private static final int DEF_PORT = 8080;
    private static final Boolean DEFAULT_START_TLS = Boolean.FALSE;
    private static final SslOption DEFAULT_SSL_OPTION = new SslOption("classpath:server.crt", "classpath:server.key", null, "classpath:ca.crt");
    private static final Boolean DEF_IS_DEBUG = Boolean.TRUE;
    private static final Set<GrantOption> DEF_GRANTS = Collections.emptySet();
    private static final int DEF_KEEP_ALIVE_TIME_SECONDS = 60;
    private static final int KEEP_ALIVE_TIME_SECONDS_MIN = 3;
    private static final int DEF_PACKET_SIZE_MAX = 8092;
    private static final int DEF_RESEND_MAX = 12;
    private static final int DEF_SOCKET_TIMEOUT_SECONDS = 15;

    /**
     * 启用?
     */
    private boolean enabled;

    /**
     * 服务端ID
     */
    private String id;

    /**
     * 服务端类型
     */
    private ServerNameOption name;

    /**
     * 端口号
     */
    private int port;

    /**
     * 启用SSL?
     */
    private boolean startTls;

    /**
     * SSL选项参数
     */
    @NestedConfigurationProperty
    private SslOption ssl;

    /**
     * 启用日志?
     */
    private Boolean debug;

    /**
     * 授权终端列表
     */
    private Set<GrantOption> grants;

    /**
     * 保持连接超时时间(单位:秒)
     */
    private int keepAliveTimeSeconds;

    /**
     * 最大数据包大小(单位:字节)
     */
    private int packetSizeMax;

    /**
     * 最大重发次数
     */
    private int resendMax;

    /**
     * 读写超时时间(单位:秒)
     */
    private int socketTimeoutSeconds;

    public NettyServerProperties() {
        this(UuidUtils.uuid(), DEF_PORT);
    }

    public NettyServerProperties(String id, int port) {
        this.enabled = DEFAULT_ENABLED;
        this.id = id;
        this.name = DEF_SERVER_NAME;
        this.port = port;
        this.startTls = DEFAULT_START_TLS;
        this.ssl = DEFAULT_SSL_OPTION;
        this.debug = DEF_IS_DEBUG;
        this.grants = DEF_GRANTS;
        this.keepAliveTimeSeconds = DEF_KEEP_ALIVE_TIME_SECONDS;
        this.packetSizeMax = DEF_PACKET_SIZE_MAX;
        this.resendMax = DEF_RESEND_MAX;
        this.socketTimeoutSeconds = DEF_SOCKET_TIMEOUT_SECONDS;
    }

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public ServerNameOption getName() {
        return name;
    }

    public void setName(ServerNameOption name) {
        this.name = name;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public boolean isStartTls() {
        return startTls;
    }

    public void setStartTls(boolean startTls) {
        this.startTls = startTls;
    }

    public SslOption getSsl() {
        return ssl;
    }

    public void setSsl(SslOption ssl) {
        this.ssl = ssl;
    }

    public Boolean isDebug() {
        return debug;
    }

    public void setDebug(Boolean debug) {
        this.debug = debug;
    }

    public Set<GrantOption> getGrants() {
        return grants;
    }

    public void setGrants(Set<GrantOption> grants) {
        this.grants = grants;
    }

    public int getKeepAliveTimeSeconds() {
        return keepAliveTimeSeconds;
    }

    public void setKeepAliveTimeSeconds(int keepAliveTimeSeconds) {
        if (keepAliveTimeSeconds < KEEP_ALIVE_TIME_SECONDS_MIN) {
            keepAliveTimeSeconds = KEEP_ALIVE_TIME_SECONDS_MIN;
        }
        this.keepAliveTimeSeconds = keepAliveTimeSeconds;
    }

    public int getPacketSizeMax() {
        return packetSizeMax;
    }

    public void setPacketSizeMax(int packetSizeMax) {
        this.packetSizeMax = packetSizeMax;
    }

    public int getResendMax() {
        return resendMax;
    }

    public void setResendMax(int resendMax) {
        this.resendMax = resendMax;
    }

    public int getSocketTimeoutSeconds() {
        return socketTimeoutSeconds;
    }

    public void setSocketTimeoutSeconds(int socketTimeoutSeconds) {
        this.socketTimeoutSeconds = socketTimeoutSeconds;
    }
}
